package com.xu.crawler.util;

import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import us.codecraft.webmagic.utils.JSONUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by clear on 2018/7/10.
 */
public class HttpClientUtils {
    private final static Logger log = LoggerFactory.getLogger(HttpClientUtils.class);

    /**
     * 实例化HttpClient
     *
     * @param maxTotal
     * @param maxPerRoute
     * @param socketTimeout
     * @param connectTimeout
     * @param connectionRequestTimeout
     * @return
     */
    public static HttpClient createHttpClient(int maxTotal, int maxPerRoute, int socketTimeout, int connectTimeout,
                                              int connectionRequestTimeout) {
//        RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout)
//                .setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectionRequestTimeout).build();
//        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
//        cm.setMaxTotal(maxTotal);
//        cm.setDefaultMaxPerRoute(maxPerRoute);
//        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
//                .setDefaultRequestConfig(defaultRequestConfig).build();
//        return httpClient;
//        CloseableHttpClient httpClient = HttpClients.custom().build();
        CloseableHttpClient httpClient = HttpClients.createDefault();
        return httpClient;

    }

    /**
     * 发送get请求
     *
     * @param httpClient
     * @param url
     * @param encoding
     * @return
     */
    public static String sendGet(HttpClient httpClient, String url, Charset encoding) {
        String resp = null;
        CloseableHttpResponse response = null;
        try {
            HttpGet httpGet = new HttpGet(url);
            httpGet.setHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36");
//            httpGet.setConfig(buildProxy());

//            SSLContext sslContext = SSLContext.getInstance("TLS");
//
//            SSLSocketFactory factory = (SSLSocketFactory) sslContext.getSocketFactory();
//            SSLSocket socket = (SSLSocket) factory.createSocket();


            System.out.println(JSONUtils.objectToStringNonEx(httpGet.getProtocolVersion()));
            System.out.println(JSONUtils.objectToStringNonEx(httpGet.getConfig()));
            response = (CloseableHttpResponse) httpClient.execute(httpGet);
            resp = EntityUtils.toString(response.getEntity(), encoding);
        } catch (Exception e) {
            log.error("httpClient sendGet {} fail: {}", url, e);
        } finally {
            closeResponse(response);
        }
        return resp;
    }


    /**
     * 发送post请求
     *
     * @param httpClient
     * @param url        请求地址
     * @param params     请求参数
     * @param encoding   编码
     * @return
     */
    public static String sendPost(HttpClient httpClient, String url, Map<String, String> params, Charset encoding) {
        String resp = null;
        CloseableHttpResponse response = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(buildProxy());
            if (params != null && params.size() > 0) {
                List<NameValuePair> formParams = new ArrayList();
                Iterator<Map.Entry<String, String>> itr = params.entrySet().iterator();
                while (itr.hasNext()) {
                    Map.Entry<String, String> entry = itr.next();
                    formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
                UrlEncodedFormEntity postEntity = new UrlEncodedFormEntity(formParams, encoding);
                httpPost.setEntity(postEntity);
            }
            response = (CloseableHttpResponse) httpClient.execute(httpPost);
            resp = EntityUtils.toString(response.getEntity(), encoding);
        } catch (Exception e) {
            log.error("httpClient sendPost {} fail: {}", url, e);
        } finally {
            closeResponse(response);
        }
        return resp;
    }

    private static RequestConfig buildProxy() {
        HttpHost proxy = new HttpHost("23.106.143.234", 25);
        return RequestConfig.custom().setProxy(proxy).build();
    }

    private static void closeResponse(CloseableHttpResponse response) {
        if (response != null) {
            try {
                response.close();
            } catch (IOException e) {
                log.error("close response fail {}", e);
            }
        }
    }


    public static void main(String[] args) throws Exception {
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, null, null);

        SSLSocketFactory factory = (SSLSocketFactory) context.getSocketFactory();
        SSLSocket socket = (SSLSocket) factory.createSocket();

        String[] protocols = socket.getSupportedProtocols();

        System.out.println("Supported Protocols: " + protocols.length);
        for (int i = 0; i < protocols.length; i++) {
            System.out.println(" " + protocols[i]);
        }

        protocols = socket.getEnabledProtocols();

        System.out.println("Enabled Protocols: " + protocols.length);
        for (int i = 0; i < protocols.length; i++) {
            System.out.println(" " + protocols[i]);
        }

    }


}
